From a69e0511cc24ac19ebed9ffe961e73767928b938 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Wed, 4 Apr 2018 17:05:37 +0200
Subject: [PATCH] wined3d: Implement GL texture access callbacks.

---
 dlls/wined3d/cs.c              | 52 ++++++++++++++++++++++++++++++++++
 dlls/wined3d/texture.c         | 10 +++++++
 dlls/wined3d/wined3d_private.h |  3 ++
 include/wine/wined3d.h         |  5 ++++
 4 files changed, 70 insertions(+)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 7e1c4ef0ecc..23a871cd815 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -73,6 +73,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW,
     WINED3D_CS_OP_COPY_UAV_COUNTER,
     WINED3D_CS_OP_GENERATE_MIPMAPS,
+    WINED3D_CS_OP_GL_TEXTURE_CALLBACK,
     WINED3D_CS_OP_STOP,
 };
 
@@ -439,6 +440,15 @@ struct wined3d_cs_generate_mipmaps
     struct wined3d_shader_resource_view *view;
 };
 
+struct wined3d_cs_gl_texture_callback
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_texture *texture;
+    wined3d_gl_texture_callback callback;
+    unsigned int data_size;
+    BYTE data[1];
+};
+
 struct wined3d_cs_stop
 {
     enum wined3d_cs_op opcode;
@@ -2496,6 +2506,47 @@ void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shad
     wined3d_cs_submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
+static void wined3d_cs_exec_gl_texture_callback(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_gl_texture_callback *op = data;
+    struct wined3d_texture_gl *texture = wined3d_texture_gl(op->texture);
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
+
+    context = context_acquire(cs->device, NULL, 0);
+    gl_info = wined3d_context_gl(context)->gl_info;
+
+    wined3d_texture_load_location(&texture->t, 0, context, WINED3D_LOCATION_TEXTURE_RGB);
+
+    op->callback(texture->texture_rgb.name, op->data, op->data_size);
+
+    context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
+    context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
+
+    checkGLcall("texture callback\n");
+
+    context_release(context);
+
+    wined3d_resource_release(&texture->t.resource);
+}
+
+void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_texture *texture,
+        wined3d_gl_texture_callback callback, const void *data, unsigned int size)
+{
+    struct wined3d_cs_gl_texture_callback *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op) + size, WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_GL_TEXTURE_CALLBACK;
+    op->texture = texture;
+    op->callback = callback;
+    op->data_size = size;
+    memcpy(op->data, data, size);
+
+    wined3d_resource_acquire(&texture->resource);
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
 static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
 {
     struct wined3d_cs_stop *op;
@@ -2556,6 +2607,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view,
     /* WINED3D_CS_OP_COPY_UAV_COUNTER            */ wined3d_cs_exec_copy_uav_counter,
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
+    /* WINED3D_CS_OP_GL_TEXTURE_CALLBACK         */ wined3d_cs_exec_gl_texture_callback,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index cb9ac2aa4ff..a881134f31a 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3864,3 +3864,13 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture,
     wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location);
     wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
 }
+
+void CDECL wined3d_access_gl_texture(struct wined3d_texture *texture,
+        wined3d_gl_texture_callback callback, const void *data, unsigned int size)
+{
+    struct wined3d_device *device = texture->resource.device;
+
+    TRACE("texture %p, callback %p, data %p, size %u.\n", texture, callback, data, size);
+
+    wined3d_cs_emit_gl_texture_callback(device->cs, texture, callback, data, size);
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 57df9f1eb24..d0872cd6cb5 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3803,6 +3803,9 @@ static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queu
     cs->ops->finish(cs, queue_id);
 }
 
+void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_texture *texture,
+        wined3d_gl_texture_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
+
 static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
         unsigned int start_idx, unsigned int count, const void *constants)
 {
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 07329024fef..17c19639ae1 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2753,6 +2753,11 @@ ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaratio
 HRESULT __cdecl wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature,
         const void *byte_code, SIZE_T byte_code_size);
 
+typedef void (__cdecl *wined3d_gl_texture_callback)(unsigned int gl_texture, const void *data, unsigned int size);
+
+void __cdecl wined3d_access_gl_texture(struct wined3d_texture *texture,
+        wined3d_gl_texture_callback callback, const void *data, unsigned int size);
+
 /* Return the integer base-2 logarithm of x. Undefined for x == 0. */
 static inline unsigned int wined3d_log2i(unsigned int x)
 {
From 20da9c119440bcf8968069340d3dce0110520f42 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Wed, 4 Apr 2018 17:05:37 +0200
Subject: [PATCH] wined3d: Implement command stream callbacks.

---
 dlls/wined3d/cs.c              | 40 ++++++++++++++++++++++++++++++++++
 dlls/wined3d/device.c          |  8 +++++++
 dlls/wined3d/wined3d_private.h |  2 ++
 include/wine/wined3d.h         |  5 +++++
 4 files changed, 55 insertions(+)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 23a871cd815..42acc62aa6d 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -74,6 +74,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_COPY_UAV_COUNTER,
     WINED3D_CS_OP_GENERATE_MIPMAPS,
     WINED3D_CS_OP_GL_TEXTURE_CALLBACK,
+    WINED3D_CS_OP_USER_CALLBACK,
     WINED3D_CS_OP_STOP,
 };
 
@@ -449,6 +450,14 @@ struct wined3d_cs_gl_texture_callback
     BYTE data[1];
 };
 
+struct wined3d_cs_user_callback
+{
+    enum wined3d_cs_op opcode;
+    wined3d_cs_callback callback;
+    unsigned int data_size;
+    BYTE data[1];
+};
+
 struct wined3d_cs_stop
 {
     enum wined3d_cs_op opcode;
@@ -2547,6 +2556,36 @@ void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_t
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
+static void wined3d_cs_exec_user_callback(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_user_callback *op = data;
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
+
+    context = context_acquire(cs->device, NULL, 0);
+    gl_info = wined3d_context_gl(context)->gl_info;
+
+    op->callback(op->data, op->data_size);
+
+    checkGLcall("user callback\n");
+
+    context_release(context);
+}
+
+void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
+        wined3d_cs_callback callback, const void *data, unsigned int size)
+{
+    struct wined3d_cs_user_callback *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op) + size, WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_USER_CALLBACK;
+    op->callback = callback;
+    op->data_size = size;
+    memcpy(op->data, data, size);
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
 static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
 {
     struct wined3d_cs_stop *op;
@@ -2608,6 +2647,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_COPY_UAV_COUNTER            */ wined3d_cs_exec_copy_uav_counter,
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
     /* WINED3D_CS_OP_GL_TEXTURE_CALLBACK         */ wined3d_cs_exec_gl_texture_callback,
+    /* WINED3D_CS_OP_USER_CALLBACK               */ wined3d_cs_exec_user_callback,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index d9d6cf26767..cba5731c3a0 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5475,3 +5475,11 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
     else
         return CallWindowProcA(proc, window, message, wparam, lparam);
 }
+
+void CDECL wined3d_device_run_cs_callback(struct wined3d_device *device,
+        wined3d_cs_callback callback, const void *data, unsigned int size)
+{
+    TRACE("device %p, callback %p, data %p, size %u.\n", device, callback, data, size);
+
+    wined3d_cs_emit_user_callback(device->cs, callback, data, size);
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d0872cd6cb5..926620b6773 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3805,6 +3805,8 @@ static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queu
 
 void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_texture *texture,
         wined3d_gl_texture_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
+        wined3d_cs_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
 
 static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
         unsigned int start_idx, unsigned int count, const void *constants)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 17c19639ae1..17acbed2988 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2758,6 +2758,11 @@ typedef void (__cdecl *wined3d_gl_texture_callback)(unsigned int gl_texture, con
 void __cdecl wined3d_access_gl_texture(struct wined3d_texture *texture,
         wined3d_gl_texture_callback callback, const void *data, unsigned int size);
 
+typedef void (__cdecl *wined3d_cs_callback)(const void *data, unsigned int size);
+
+void __cdecl wined3d_device_run_cs_callback(struct wined3d_device *device,
+        wined3d_cs_callback callback, const void *data, unsigned int size);
+
 /* Return the integer base-2 logarithm of x. Undefined for x == 0. */
 static inline unsigned int wined3d_log2i(unsigned int x)
 {
From b1b19abce8d3695aa35a6bfefb5c5aee9748c4ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Wed, 4 Apr 2018 17:05:37 +0200
Subject: [PATCH] d3d11: Add IWineD3D11Texture2D interface.

---
 dlls/d3d11/d3d11_private.h       |  4 +-
 dlls/d3d11/device.c              |  4 +-
 dlls/d3d11/texture.c             | 65 +++++++++++++++++++++-----------
 include/Makefile.in              |  1 +
 include/wine/wined3d-interop.idl | 31 +++++++++++++++
 5 files changed, 80 insertions(+), 25 deletions(-)
 create mode 100644 include/wine/wined3d-interop.idl

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 44e774b8b4d..7b1c8c91f87 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -39,6 +39,8 @@
 #include "wine/winedxgi.h"
 #include "wine/rbtree.h"
 
+#include "wine/wined3d-interop.h"
+
 #define MAKE_TAG(ch0, ch1, ch2, ch3) \
     ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \
     ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 ))
@@ -124,7 +126,7 @@ struct d3d_texture1d *unsafe_impl_from_ID3D10Texture1D(ID3D10Texture1D *iface) D
 /* ID3D11Texture2D, ID3D10Texture2D */
 struct d3d_texture2d
 {
-    ID3D11Texture2D ID3D11Texture2D_iface;
+    IWineD3D11Texture2D ID3D11Texture2D_iface;
     ID3D10Texture2D ID3D10Texture2D_iface;
     LONG refcount;
 
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 7ad3d9b5e9b..ad5bfa985c3 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -2859,7 +2859,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture2D(ID3D11Device2 *ifa
     if (FAILED(hr = d3d_texture2d_create(device, desc, data, &object)))
         return hr;
 
-    *texture = &object->ID3D11Texture2D_iface;
+    *texture = (ID3D11Texture2D *)&object->ID3D11Texture2D_iface;
 
     return S_OK;
 }
@@ -6100,7 +6100,7 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic
 
     *wined3d_texture = texture->wined3d_texture;
     wined3d_texture_incref(*wined3d_texture);
-    ID3D11Texture2D_Release(&texture->ID3D11Texture2D_iface);
+    IWineD3D11Texture2D_Release(&texture->ID3D11Texture2D_iface);
 
     return S_OK;
 }
diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index 78821955604..bf6fd4e8b9d 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -521,13 +521,20 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE
 
 /* ID3D11Texture2D methods */
 
-static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D *iface, REFIID riid, void **object)
+static inline struct d3d_texture2d *impl_from_IWineD3D11Texture2D(IWineD3D11Texture2D *iface)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D11Texture2D_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(IWineD3D11Texture2D *iface,
+        REFIID riid, void **object)
+{
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
 
     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
 
-    if (IsEqualGUID(riid, &IID_ID3D11Texture2D)
+    if (IsEqualGUID(riid, &IID_IWineD3D11Texture2D)
+            || IsEqualGUID(riid, &IID_ID3D11Texture2D)
             || IsEqualGUID(riid, &IID_ID3D11Resource)
             || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
             || IsEqualGUID(riid, &IID_IUnknown))
@@ -557,9 +564,9 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D
     return E_NOINTERFACE;
 }
 
-static ULONG STDMETHODCALLTYPE d3d11_texture2d_AddRef(ID3D11Texture2D *iface)
+static ULONG STDMETHODCALLTYPE d3d11_texture2d_AddRef(IWineD3D11Texture2D *iface)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     ULONG refcount = InterlockedIncrement(&texture->refcount);
 
     TRACE("%p increasing refcount to %u.\n", texture, refcount);
@@ -575,9 +582,9 @@ static ULONG STDMETHODCALLTYPE d3d11_texture2d_AddRef(ID3D11Texture2D *iface)
     return refcount;
 }
 
-static ULONG STDMETHODCALLTYPE d3d11_texture2d_Release(ID3D11Texture2D *iface)
+static ULONG STDMETHODCALLTYPE d3d11_texture2d_Release(IWineD3D11Texture2D *iface)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     ULONG refcount = InterlockedDecrement(&texture->refcount);
 
     TRACE("%p decreasing refcount to %u.\n", texture, refcount);
@@ -597,9 +604,9 @@ static ULONG STDMETHODCALLTYPE d3d11_texture2d_Release(ID3D11Texture2D *iface)
     return refcount;
 }
 
-static void STDMETHODCALLTYPE d3d11_texture2d_GetDevice(ID3D11Texture2D *iface, ID3D11Device **device)
+static void STDMETHODCALLTYPE d3d11_texture2d_GetDevice(IWineD3D11Texture2D *iface, ID3D11Device **device)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
 
     TRACE("iface %p, device %p.\n", iface, device);
 
@@ -607,10 +614,10 @@ static void STDMETHODCALLTYPE d3d11_texture2d_GetDevice(ID3D11Texture2D *iface,
     ID3D11Device_AddRef(*device);
 }
 
-static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D *iface,
+static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(IWineD3D11Texture2D *iface,
         REFGUID guid, UINT *data_size, void *data)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     IDXGISurface *dxgi_surface;
     HRESULT hr;
 
@@ -627,10 +634,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D
     return d3d_get_private_data(&texture->private_store, guid, data_size, data);
 }
 
-static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D *iface,
+static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(IWineD3D11Texture2D *iface,
         REFGUID guid, UINT data_size, const void *data)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     IDXGISurface *dxgi_surface;
     HRESULT hr;
 
@@ -647,10 +654,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D
     return d3d_set_private_data(&texture->private_store, guid, data_size, data);
 }
 
-static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11Texture2D *iface,
+static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(IWineD3D11Texture2D *iface,
         REFGUID guid, const IUnknown *data)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     IDXGISurface *dxgi_surface;
     HRESULT hr;
 
@@ -667,7 +674,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11T
     return d3d_set_private_data_interface(&texture->private_store, guid, data);
 }
 
-static void STDMETHODCALLTYPE d3d11_texture2d_GetType(ID3D11Texture2D *iface,
+static void STDMETHODCALLTYPE d3d11_texture2d_GetType(IWineD3D11Texture2D *iface,
         D3D11_RESOURCE_DIMENSION *resource_dimension)
 {
     TRACE("iface %p, resource_dimension %p.\n", iface, resource_dimension);
@@ -675,21 +682,21 @@ static void STDMETHODCALLTYPE d3d11_texture2d_GetType(ID3D11Texture2D *iface,
     *resource_dimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D;
 }
 
-static void STDMETHODCALLTYPE d3d11_texture2d_SetEvictionPriority(ID3D11Texture2D *iface, UINT eviction_priority)
+static void STDMETHODCALLTYPE d3d11_texture2d_SetEvictionPriority(IWineD3D11Texture2D *iface, UINT eviction_priority)
 {
     FIXME("iface %p, eviction_priority %#x stub!\n", iface, eviction_priority);
 }
 
-static UINT STDMETHODCALLTYPE d3d11_texture2d_GetEvictionPriority(ID3D11Texture2D *iface)
+static UINT STDMETHODCALLTYPE d3d11_texture2d_GetEvictionPriority(IWineD3D11Texture2D *iface)
 {
     FIXME("iface %p stub!\n", iface);
 
     return 0;
 }
 
-static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(ID3D11Texture2D *iface, D3D11_TEXTURE2D_DESC *desc)
+static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(IWineD3D11Texture2D *iface, D3D11_TEXTURE2D_DESC *desc)
 {
-    struct d3d_texture2d *texture = impl_from_ID3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     struct wined3d_resource_desc wined3d_desc;
 
     TRACE("iface %p, desc %p.\n", iface, desc);
@@ -711,7 +718,19 @@ static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(ID3D11Texture2D *iface, D3
     desc->SampleDesc.Quality = wined3d_desc.multisample_quality;
 }
 
-static const struct ID3D11Texture2DVtbl d3d11_texture2d_vtbl =
+static void STDMETHODCALLTYPE d3d11_texture2d_access_gl_texture(IWineD3D11Texture2D *iface,
+        gl_texture_callback callback, const void *data, unsigned int size)
+{
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
+
+    TRACE("iface %p, callback %p, data %p, size %u.\n", iface, callback, data, size);
+
+    wined3d_mutex_lock();
+    wined3d_access_gl_texture(texture->wined3d_texture, callback, data, size);
+    wined3d_mutex_unlock();
+}
+
+static const struct IWineD3D11Texture2DVtbl d3d11_texture2d_vtbl =
 {
     /* IUnknown methods */
     d3d11_texture2d_QueryInterface,
@@ -728,13 +747,15 @@ static const struct ID3D11Texture2DVtbl d3d11_texture2d_vtbl =
     d3d11_texture2d_GetEvictionPriority,
     /* ID3D11Texture2D methods */
     d3d11_texture2d_GetDesc,
+    /* IWineD3D11Texture methods */
+    d3d11_texture2d_access_gl_texture,
 };
 
 struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface)
 {
     if (!iface)
         return NULL;
-    assert(iface->lpVtbl == &d3d11_texture2d_vtbl);
+    assert(iface->lpVtbl == (void *)&d3d11_texture2d_vtbl);
     return CONTAINING_RECORD(iface, struct d3d_texture2d, ID3D11Texture2D_iface);
 }
 
diff --git a/include/Makefile.in b/include/Makefile.in
index bd7b767e46..5067617fc5 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -705,6 +705,7 @@ SOURCES = \
 	wine/itss.idl \
 	wine/library.h \
 	wine/svcctl.idl \
+	wine/wined3d-interop.idl \
 	wine/winedxgi.idl \
 	winerror.h \
 	winevt.h \
diff --git a/include/wine/wined3d-interop.idl b/include/wine/wined3d-interop.idl
new file mode 100644
index 00000000000..884baf958c2
--- /dev/null
+++ b/include/wine/wined3d-interop.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Józef Kucia for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+typedef void (__cdecl *gl_texture_callback)(unsigned int gl_texture, const void *data, unsigned int data_size);
+
+import "d3d11.idl";
+
+[
+    object,
+    local,
+    uuid(267dc993-d15e-4015-aaac-b7559e226cc3)
+]
+interface IWineD3D11Texture2D : ID3D11Texture2D
+{
+    void access_gl_texture(gl_texture_callback callback, const void *data, unsigned int data_size);
+}
From fdb6a5f0385850765335bbe312ad188a3e8ebe51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Wed, 4 Apr 2018 17:05:37 +0200
Subject: [PATCH] d3d11: Add IWineD3D11Device interface.

---
 dlls/d3d11/d3d11_private.h       |  1 +
 dlls/d3d11/device.c              | 52 ++++++++++++++++++++++++++++++++
 include/wine/wined3d-interop.idl | 12 ++++++++
 3 files changed, 65 insertions(+)

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 7b1c8c91f87..9364a6304a2 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -515,6 +515,7 @@ struct d3d_device
     ID3D10Multithread ID3D10Multithread_iface;
     IWineDXGIDeviceParent IWineDXGIDeviceParent_iface;
     IUnknown *outer_unk;
+    IWineD3D11Device IWineD3D11Device_iface;
     LONG refcount;
 
     D3D_FEATURE_LEVEL feature_level;
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index ad5bfa985c3..9a261c54588 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -2813,6 +2813,53 @@ static ULONG STDMETHODCALLTYPE d3d11_device_Release(ID3D11Device2 *iface)
     return IUnknown_Release(device->outer_unk);
 }
 
+/* IWineD3D11Device methods */
+
+static inline struct d3d_device *impl_from_IWineD3D11Device(IWineD3D11Device *iface)
+{
+    return CONTAINING_RECORD(iface, struct d3d_device, IWineD3D11Device_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE wine_device_QueryInterface(IWineD3D11Device *iface, REFIID riid, void **out)
+{
+    struct d3d_device *device = impl_from_IWineD3D11Device(iface);
+    return IUnknown_QueryInterface(device->outer_unk, riid, out);
+}
+
+static ULONG STDMETHODCALLTYPE wine_device_AddRef(IWineD3D11Device *iface)
+{
+    struct d3d_device *device = impl_from_IWineD3D11Device(iface);
+    return IUnknown_AddRef(device->outer_unk);
+}
+
+static ULONG STDMETHODCALLTYPE wine_device_Release(IWineD3D11Device *iface)
+{
+    struct d3d_device *device = impl_from_IWineD3D11Device(iface);
+    return IUnknown_Release(device->outer_unk);
+}
+
+static void STDMETHODCALLTYPE wine_device_run_on_command_stream(IWineD3D11Device *iface,
+        user_cs_callback callback, const void *data, unsigned int data_size)
+{
+    struct d3d_device *device = impl_from_IWineD3D11Device(iface);
+
+    TRACE("iface %p, callback %p, data %p, data_size %u.\n", iface, callback, data, data_size);
+
+    wined3d_mutex_lock();
+    wined3d_device_run_cs_callback(device->wined3d_device, callback, data, data_size);
+    wined3d_mutex_unlock();
+}
+
+static const struct IWineD3D11DeviceVtbl wine_device_vtbl =
+{
+    /* IUnknown methods */
+    wine_device_QueryInterface,
+    wine_device_AddRef,
+    wine_device_Release,
+    /* IWineD3D11Device methods */
+    wine_device_run_on_command_stream,
+};
+
 static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBuffer(ID3D11Device2 *iface, const D3D11_BUFFER_DESC *desc,
         const D3D11_SUBRESOURCE_DATA *data, ID3D11Buffer **buffer)
 {
@@ -3840,6 +3887,10 @@ static HRESULT STDMETHODCALLTYPE d3d_device_inner_QueryInterface(IUnknown *iface
     {
         *out = &device->IWineDXGIDeviceParent_iface;
     }
+    else if (IsEqualGUID(riid, &IID_IWineD3D11Device))
+    {
+        *out = &device->IWineD3D11Device_iface;
+    }
     else
     {
         WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
@@ -6182,6 +6233,7 @@ void d3d_device_init(struct d3d_device *device, void *outer_unknown)
     device->ID3D10Device1_iface.lpVtbl = &d3d10_device1_vtbl;
     device->ID3D10Multithread_iface.lpVtbl = &d3d10_multithread_vtbl;
     device->IWineDXGIDeviceParent_iface.lpVtbl = &d3d_dxgi_device_parent_vtbl;
+    device->IWineD3D11Device_iface.lpVtbl = &wine_device_vtbl;
     device->device_parent.ops = &d3d_wined3d_device_parent_ops;
     device->refcount = 1;
     /* COM aggregation always takes place */
diff --git a/include/wine/wined3d-interop.idl b/include/wine/wined3d-interop.idl
index 884baf958c2..d5c91623b3c 100644
--- a/include/wine/wined3d-interop.idl
+++ b/include/wine/wined3d-interop.idl
@@ -29,3 +29,15 @@ interface IWineD3D11Texture2D : ID3D11Texture2D
 {
     void access_gl_texture(gl_texture_callback callback, const void *data, unsigned int data_size);
 }
+
+typedef void (__cdecl *user_cs_callback)(const void *data, unsigned int data_size);
+
+[
+    object,
+    local,
+    uuid(8f02de7e-d55d-457b-9423-83456e49c58a)
+]
+interface IWineD3D11Device : IUnknown
+{
+    void run_on_command_stream(user_cs_callback callback, const void *data, unsigned int data_size);
+}
From 75ccc1309e00683db7f35598f9b1f99293019743 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Thu, 19 Apr 2018 14:04:49 +0200
Subject: [PATCH] wined3d: Implement wined3d_device_wait_idle().

---
 dlls/d3d11/device.c              | 12 ++++++++++++
 dlls/wined3d/cs.c                | 20 ++++++++++++++++++++
 dlls/wined3d/device.c            |  7 +++++++
 dlls/wined3d/wined3d_private.h   |  1 +
 include/wine/wined3d-interop.idl |  2 ++
 include/wine/wined3d.h           |  1 +
 6 files changed, 43 insertions(+)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 9a261c54588..76e1849425a 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -2850,6 +2850,17 @@ static void STDMETHODCALLTYPE wine_device_run_on_command_stream(IWineD3D11Device
     wined3d_mutex_unlock();
 }
 
+static void STDMETHODCALLTYPE wine_device_wait_idle(IWineD3D11Device *iface)
+{
+    struct d3d_device *device = impl_from_IWineD3D11Device(iface);
+
+    TRACE("iface %p.\n", iface);
+
+    wined3d_mutex_lock();
+    wined3d_device_wait_idle(device->wined3d_device);
+    wined3d_mutex_unlock();
+}
+
 static const struct IWineD3D11DeviceVtbl wine_device_vtbl =
 {
     /* IUnknown methods */
@@ -2858,6 +2869,7 @@ static const struct IWineD3D11DeviceVtbl wine_device_vtbl =
     wine_device_Release,
     /* IWineD3D11Device methods */
     wine_device_run_on_command_stream,
+    wine_device_wait_idle,
 };
 
 static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBuffer(ID3D11Device2 *iface, const D3D11_BUFFER_DESC *desc,
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 42acc62aa6d..abfcf3f9404 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -75,6 +75,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_GENERATE_MIPMAPS,
     WINED3D_CS_OP_GL_TEXTURE_CALLBACK,
     WINED3D_CS_OP_USER_CALLBACK,
+    WINED3D_CS_OP_WAIT_IDLE,
     WINED3D_CS_OP_STOP,
 };
 
@@ -458,6 +459,11 @@ struct wined3d_cs_user_callback
     BYTE data[1];
 };
 
+struct wined3d_cs_wait_idle
+{
+    enum wined3d_cs_op opcode;
+};
+
 struct wined3d_cs_stop
 {
     enum wined3d_cs_op opcode;
@@ -2586,6 +2592,19 @@ void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
+static void wined3d_cs_exec_wait_idle(struct wined3d_cs *cs, const void *data) {}
+
+void wined3d_cs_emit_wait_idle(struct wined3d_cs *cs)
+{
+    struct wined3d_cs_wait_idle *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_WAIT_IDLE;
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+    cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
 static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
 {
     struct wined3d_cs_stop *op;
@@ -2648,6 +2667,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
     /* WINED3D_CS_OP_GL_TEXTURE_CALLBACK         */ wined3d_cs_exec_gl_texture_callback,
     /* WINED3D_CS_OP_USER_CALLBACK               */ wined3d_cs_exec_user_callback,
+    /* WINED3D_CS_OP_WAIT_IDLE                   */ wined3d_cs_exec_wait_idle,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cba5731c3a0..db0ccca7d54 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5483,3 +5483,10 @@ void CDECL wined3d_device_run_cs_callback(struct wined3d_device *device,
 
     wined3d_cs_emit_user_callback(device->cs, callback, data, size);
 }
+
+void CDECL wined3d_device_wait_idle(struct wined3d_device *device)
+{
+    TRACE("device %p.\n", device);
+
+    wined3d_cs_emit_wait_idle(device->cs);
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 926620b6773..ada8c90f422 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3807,6 +3807,7 @@ void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_t
         wined3d_gl_texture_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
         wined3d_cs_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_wait_idle(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 
 static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
         unsigned int start_idx, unsigned int count, const void *constants)
diff --git a/include/wine/wined3d-interop.idl b/include/wine/wined3d-interop.idl
index d5c91623b3c..6f8ea3770e3 100644
--- a/include/wine/wined3d-interop.idl
+++ b/include/wine/wined3d-interop.idl
@@ -40,4 +40,6 @@ typedef void (__cdecl *user_cs_callback)(const void *data, unsigned int data_siz
 interface IWineD3D11Device : IUnknown
 {
     void run_on_command_stream(user_cs_callback callback, const void *data, unsigned int data_size);
+
+    void wait_idle();
 }
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 17acbed2988..8d4142e2519 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2762,6 +2762,7 @@ typedef void (__cdecl *wined3d_cs_callback)(const void *data, unsigned int size)
 
 void __cdecl wined3d_device_run_cs_callback(struct wined3d_device *device,
         wined3d_cs_callback callback, const void *data, unsigned int size);
+void __cdecl wined3d_device_wait_idle(struct wined3d_device *device);
 
 /* Return the integer base-2 logarithm of x. Undefined for x == 0. */
 static inline unsigned int wined3d_log2i(unsigned int x)
From 49cee05db3bbec90879588b052c8e82386430e99 Mon Sep 17 00:00:00 2001
From: Andrew Eikum <aeikum@codeweavers.com>
Date: Tue, 1 May 2018 15:06:30 -0500
Subject: [PATCH] wined3d: Support retrieving depth texture in GL texture
 callback

---
 dlls/d3d11/texture.c             | 20 +++++++++++++++++---
 dlls/wined3d/cs.c                | 14 ++++++++++++--
 dlls/wined3d/texture.c           |  7 ++++---
 dlls/wined3d/wined3d_private.h   |  3 ++-
 include/wine/wined3d-interop.idl |  4 ++--
 include/wine/wined3d.h           |  4 ++--
 6 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index bf6fd4e8b9d..58a7633f78c 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -719,14 +719,28 @@ static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(IWineD3D11Texture2D *iface
 }
 
 static void STDMETHODCALLTYPE d3d11_texture2d_access_gl_texture(IWineD3D11Texture2D *iface,
-        gl_texture_callback callback, const void *data, unsigned int size)
+        gl_texture_callback callback, IUnknown *depth_unk, const void *data, unsigned int size)
 {
-    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface), *depth_tex = NULL;
+    IWineD3D11Texture2D *depth_d3d11 = NULL;
 
     TRACE("iface %p, callback %p, data %p, size %u.\n", iface, callback, data, size);
 
     wined3d_mutex_lock();
-    wined3d_access_gl_texture(texture->wined3d_texture, callback, data, size);
+
+    if (depth_unk)
+    {
+        HRESULT hr;
+        hr = IUnknown_QueryInterface(depth_unk, &IID_IWineD3D11Texture2D, (void**)&depth_d3d11);
+        if(hr == S_OK)
+            depth_tex = impl_from_IWineD3D11Texture2D(depth_d3d11);
+    }
+
+    wined3d_access_gl_texture(texture->wined3d_texture, callback, depth_tex ? depth_tex->wined3d_texture : NULL, data, size);
+
+    if (depth_d3d11)
+        IWineD3D11Texture2D_Release(depth_d3d11);
+
     wined3d_mutex_unlock();
 }
 
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index abfcf3f9404..5a204693abb 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -446,6 +446,7 @@ struct wined3d_cs_gl_texture_callback
 {
     enum wined3d_cs_op opcode;
     struct wined3d_texture *texture;
+    struct wined3d_texture *depth_texture;
     wined3d_gl_texture_callback callback;
     unsigned int data_size;
     BYTE data[1];
@@ -2525,6 +2526,7 @@ static void wined3d_cs_exec_gl_texture_callback(struct wined3d_cs *cs, const voi
 {
     const struct wined3d_cs_gl_texture_callback *op = data;
     struct wined3d_texture_gl *texture = wined3d_texture_gl(op->texture);
+    struct wined3d_texture_gl *depth_texture = wined3d_texture_gl(op->depth_texture);
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
 
@@ -2532,8 +2534,12 @@ static void wined3d_cs_exec_gl_texture_callback(struct wined3d_cs *cs, const voi
     gl_info = wined3d_context_gl(context)->gl_info;
 
     wined3d_texture_load_location(&texture->t, 0, context, WINED3D_LOCATION_TEXTURE_RGB);
+    if (depth_texture)
+        wined3d_texture_load_location(&depth_texture->t, 0, context, WINED3D_LOCATION_TEXTURE_RGB);
 
-    op->callback(texture->texture_rgb.name, op->data, op->data_size);
+    op->callback(texture->texture_rgb.name,
+            depth_texture ? depth_texture->texture_rgb.name : 0,
+            op->data, op->data_size);
 
     context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
     context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
@@ -2542,17 +2548,21 @@ static void wined3d_cs_exec_gl_texture_callback(struct wined3d_cs *cs, const voi
 
     context_release(context);
 
+    if (depth_texture)
+        wined3d_resource_release(&depth_texture->t.resource);
     wined3d_resource_release(&texture->t.resource);
 }
 
 void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_texture *texture,
-        wined3d_gl_texture_callback callback, const void *data, unsigned int size)
+        wined3d_gl_texture_callback callback, struct wined3d_texture *depth_texture,
+        const void *data, unsigned int size)
 {
     struct wined3d_cs_gl_texture_callback *op;
 
     op = cs->ops->require_space(cs, sizeof(*op) + size, WINED3D_CS_QUEUE_DEFAULT);
     op->opcode = WINED3D_CS_OP_GL_TEXTURE_CALLBACK;
     op->texture = texture;
+    op->depth_texture = depth_texture;
     op->callback = callback;
     op->data_size = size;
     memcpy(op->data, data, size);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index a881134f31a..7ecaed1a038 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3866,11 +3866,12 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture,
 }
 
 void CDECL wined3d_access_gl_texture(struct wined3d_texture *texture,
-        wined3d_gl_texture_callback callback, const void *data, unsigned int size)
+        wined3d_gl_texture_callback callback, struct wined3d_texture *depth_texture,
+        const void *data, unsigned int size)
 {
     struct wined3d_device *device = texture->resource.device;
 
-    TRACE("texture %p, callback %p, data %p, size %u.\n", texture, callback, data, size);
+    TRACE("texture %p, depth_texture %p, callback %p, data %p, size %u.\n", texture, depth_texture, callback, data, size);
 
-    wined3d_cs_emit_gl_texture_callback(device->cs, texture, callback, data, size);
+    wined3d_cs_emit_gl_texture_callback(device->cs, texture, callback, depth_texture, data, size);
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ada8c90f422..50897f29271 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3804,7 +3804,8 @@ static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queu
 }
 
 void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_texture *texture,
-        wined3d_gl_texture_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
+        wined3d_gl_texture_callback callback, struct wined3d_texture *depth_texture,
+        const void *data, unsigned int size) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
         wined3d_cs_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_wait_idle(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d-interop.idl b/include/wine/wined3d-interop.idl
index 6f8ea3770e3..c5395ccc0ed 100644
--- a/include/wine/wined3d-interop.idl
+++ b/include/wine/wined3d-interop.idl
@@ -16,7 +16,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-typedef void (__cdecl *gl_texture_callback)(unsigned int gl_texture, const void *data, unsigned int data_size);
+typedef void (__cdecl *gl_texture_callback)(unsigned int gl_texture, unsigned int gl_depth_texture, const void *data, unsigned int data_size);
 
 import "d3d11.idl";
 
@@ -27,7 +27,7 @@ import "d3d11.idl";
 ]
 interface IWineD3D11Texture2D : ID3D11Texture2D
 {
-    void access_gl_texture(gl_texture_callback callback, const void *data, unsigned int data_size);
+    void access_gl_texture(gl_texture_callback callback, IUnknown *depth_texture, const void *data, unsigned int data_size);
 }
 
 typedef void (__cdecl *user_cs_callback)(const void *data, unsigned int data_size);
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 8d4142e2519..4754901265f 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2753,10 +2753,10 @@ ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaratio
 HRESULT __cdecl wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature,
         const void *byte_code, SIZE_T byte_code_size);
 
-typedef void (__cdecl *wined3d_gl_texture_callback)(unsigned int gl_texture, const void *data, unsigned int size);
+typedef void (__cdecl *wined3d_gl_texture_callback)(unsigned int gl_texture, unsigned int gl_depth_texture, const void *data, unsigned int size);
 
 void __cdecl wined3d_access_gl_texture(struct wined3d_texture *texture,
-        wined3d_gl_texture_callback callback, const void *data, unsigned int size);
+        wined3d_gl_texture_callback callback, struct wined3d_texture *depth_texture, const void *data, unsigned int size);
 
 typedef void (__cdecl *wined3d_cs_callback)(const void *data, unsigned int size);
 
From 33441488f08d06ea4e8462e9012da0ce4c73d7dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Tue, 18 Sep 2018 23:10:14 +0200
Subject: [PATCH] wined3d: Get rid of wined3d_cs_emit_wait_idle().

---
 dlls/wined3d/cs.c              | 15 ---------------
 dlls/wined3d/device.c          |  2 +-
 dlls/wined3d/wined3d_private.h |  1 -
 3 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 5a204693abb..da802ee2e49 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -75,7 +75,6 @@ enum wined3d_cs_op
     WINED3D_CS_OP_GENERATE_MIPMAPS,
     WINED3D_CS_OP_GL_TEXTURE_CALLBACK,
     WINED3D_CS_OP_USER_CALLBACK,
-    WINED3D_CS_OP_WAIT_IDLE,
     WINED3D_CS_OP_STOP,
 };
 
@@ -2602,19 +2601,6 @@ void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
-static void wined3d_cs_exec_wait_idle(struct wined3d_cs *cs, const void *data) {}
-
-void wined3d_cs_emit_wait_idle(struct wined3d_cs *cs)
-{
-    struct wined3d_cs_wait_idle *op;
-
-    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
-    op->opcode = WINED3D_CS_OP_WAIT_IDLE;
-
-    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
-    cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT);
-}
-
 static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
 {
     struct wined3d_cs_stop *op;
@@ -2677,7 +2663,6 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
     /* WINED3D_CS_OP_GL_TEXTURE_CALLBACK         */ wined3d_cs_exec_gl_texture_callback,
     /* WINED3D_CS_OP_USER_CALLBACK               */ wined3d_cs_exec_user_callback,
-    /* WINED3D_CS_OP_WAIT_IDLE                   */ wined3d_cs_exec_wait_idle,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index db0ccca7d54..0c48e5fcc82 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5488,5 +5488,5 @@ void CDECL wined3d_device_wait_idle(struct wined3d_device *device)
 {
     TRACE("device %p.\n", device);
 
-    wined3d_cs_emit_wait_idle(device->cs);
+    device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 50897f29271..519b0292483 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3808,7 +3808,6 @@ void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_t
         const void *data, unsigned int size) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
         wined3d_cs_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
-void wined3d_cs_emit_wait_idle(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
 
 static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
         unsigned int start_idx, unsigned int count, const void *constants)
From 32d6ac6c383d710b07fb75668ab6ccc6a8644238 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Tue, 18 Sep 2018 22:04:21 +0200
Subject: [PATCH] wined3d: Implement synchronous texture access.

For vrclient.
---
 dlls/d3d11/texture.c             |  15 ++++
 dlls/wined3d/cs.c                |  48 ++++++++++++
 dlls/wined3d/device.c            |   2 +
 dlls/wined3d/texture.c           | 123 +++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h   |  14 ++++
 include/wine/wined3d-interop.idl |   2 +
 include/wine/wined3d.h           |   2 +
 7 files changed, 206 insertions(+)

diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index 58a7633f78c..95328043789 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -744,6 +744,20 @@ static void STDMETHODCALLTYPE d3d11_texture2d_access_gl_texture(IWineD3D11Textur
     wined3d_mutex_unlock();
 }
 
+static unsigned int STDMETHODCALLTYPE d3d11_texture2d_get_gl_texture(IWineD3D11Texture2D *iface)
+{
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
+    unsigned int id;
+
+    TRACE("iface %p.\n", iface);
+
+    wined3d_mutex_lock();
+    id = wined3d_get_gl_texture(texture->wined3d_texture);
+    wined3d_mutex_unlock();
+
+    return id;
+}
+
 static const struct IWineD3D11Texture2DVtbl d3d11_texture2d_vtbl =
 {
     /* IUnknown methods */
@@ -763,6 +777,7 @@ static const struct IWineD3D11Texture2DVtbl d3d11_texture2d_vtbl =
     d3d11_texture2d_GetDesc,
     /* IWineD3D11Texture methods */
     d3d11_texture2d_access_gl_texture,
+    d3d11_texture2d_get_gl_texture,
 };
 
 struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index da802ee2e49..1f1883cafea 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -75,6 +75,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_GENERATE_MIPMAPS,
     WINED3D_CS_OP_GL_TEXTURE_CALLBACK,
     WINED3D_CS_OP_USER_CALLBACK,
+    WINED3D_CS_OP_FENCE,
     WINED3D_CS_OP_STOP,
 };
 
@@ -464,6 +465,12 @@ struct wined3d_cs_wait_idle
     enum wined3d_cs_op opcode;
 };
 
+struct wined3d_cs_fence
+{
+    enum wined3d_cs_op opcode;
+    GLsync *fence;
+};
+
 struct wined3d_cs_stop
 {
     enum wined3d_cs_op opcode;
@@ -2601,6 +2608,46 @@ void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
 
+static void wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_fence *op = data;
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
+    GLsync fence;
+
+    context = context_acquire(cs->device, NULL, 0);
+    gl_info = wined3d_context_gl(context)->gl_info;
+
+    fence = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
+    wined3d_context_gl(context)->gl_info->gl_ops.gl.p_glFlush();
+
+    *op->fence = fence;
+
+    checkGLcall("fence");
+
+    context_release(context);
+}
+
+static GLsync wined3d_cs_emit_fence(struct wined3d_cs *cs)
+{
+    struct wined3d_cs_fence *op;
+    GLsync fence;
+
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_FENCE;
+    op->fence = &fence;
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+    cs->ops->finish(cs, WINED3D_CS_QUEUE_DEFAULT);
+
+    return fence;
+}
+
+GLsync wined3d_cs_synchronize(struct wined3d_cs *cs)
+{
+    return wined3d_cs_emit_fence(cs);
+}
+
 static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
 {
     struct wined3d_cs_stop *op;
@@ -2663,6 +2710,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_GENERATE_MIPMAPS            */ wined3d_cs_exec_generate_mipmaps,
     /* WINED3D_CS_OP_GL_TEXTURE_CALLBACK         */ wined3d_cs_exec_gl_texture_callback,
     /* WINED3D_CS_OP_USER_CALLBACK               */ wined3d_cs_exec_user_callback,
+    /* WINED3D_CS_OP_FENCE                       */ wined3d_cs_exec_fence,
 };
 
 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 751676b75a..81f076c02e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -540,6 +540,8 @@ void wined3d_device_cleanup(struct wined3d_device *device)
 
     wined3d_stateblock_state_cleanup(&device->stateblock_state);
 
+    wined3d_destroy_gl_vr_context(&device->vr_context);
+
     wined3d_cs_destroy(device->cs);
 
     if (device->recording && wined3d_stateblock_decref(device->recording))
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 7ecaed1a038..bb2a557c972 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3875,3 +3875,126 @@ void CDECL wined3d_access_gl_texture(struct wined3d_texture *texture,
 
     wined3d_cs_emit_gl_texture_callback(device->cs, texture, callback, depth_texture, data, size);
 }
+
+static const struct wined3d_gl_info *wined3d_prepare_vr_gl_context(struct wined3d_device *device)
+{
+    const struct wined3d_adapter *adapter = device->adapter;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    struct wined3d_vr_gl_context *ctx = &device->vr_context;
+    PIXELFORMATDESCRIPTOR pfd;
+    int pixel_format;
+    HGLRC share_ctx;
+
+    if (ctx->gl_info)
+        return gl_info;
+
+    TRACE("Creating GL context.\n");
+
+    if (!gl_info->p_wglCreateContextAttribsARB)
+    {
+        ERR("wglCreateContextAttribsARB is not supported.\n");
+        return NULL;
+    }
+
+    if (!gl_info->supported[ARB_SYNC])
+    {
+        FIXME("ARB_sync is not supported.\n");
+        return NULL;
+    }
+
+    ctx->window = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D VR window",
+            WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
+    if (!ctx->window)
+    {
+        ERR("Failed to create a window.\n");
+        return NULL;
+    }
+
+    ctx->dc = GetDC(ctx->window);
+    if (!ctx->dc)
+    {
+        ERR("Failed to get a DC.\n");
+        goto fail;
+    }
+
+    memset(&pfd, 0, sizeof(pfd));
+    pfd.nSize = sizeof(pfd);
+    pfd.nVersion = 1;
+    pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = 32;
+    pfd.iLayerType = PFD_MAIN_PLANE;
+
+    if (!(pixel_format = ChoosePixelFormat(ctx->dc, &pfd)))
+    {
+        ERR("Failed to find a suitable pixel format.\n");
+        goto fail;
+    }
+    DescribePixelFormat(ctx->dc, pixel_format, sizeof(pfd), &pfd);
+    SetPixelFormat(ctx->dc, pixel_format, &pfd);
+
+    share_ctx = device->context_count ? wined3d_context_gl(device->contexts[0])->gl_ctx : NULL;
+    if (!(ctx->gl_ctx = context_create_wgl_attribs(gl_info, ctx->dc, share_ctx)))
+    {
+        WARN("Failed to create GL context for VR.\n");
+        goto fail;
+    }
+
+    if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx))
+    {
+        ERR("Failed to make GL context current.\n");
+        goto fail;
+    }
+
+    checkGLcall("create context");
+
+    ctx->gl_info = gl_info;
+    return gl_info;
+
+fail:
+    if (ctx->gl_ctx)
+        wglDeleteContext(ctx->gl_ctx);
+    ctx->gl_ctx = NULL;
+    if (ctx->dc)
+        ReleaseDC(ctx->window, ctx->dc);
+    ctx->dc = NULL;
+    if (ctx->window)
+        DestroyWindow(ctx->window);
+    ctx->window = NULL;
+    return NULL;
+}
+
+void wined3d_destroy_gl_vr_context(struct wined3d_vr_gl_context *ctx)
+{
+    if (!ctx->gl_info)
+        return;
+
+    TRACE("Destroying GL context.\n");
+
+    wglMakeCurrent(NULL, NULL);
+    wglDeleteContext(ctx->gl_ctx);
+    ReleaseDC(ctx->window, ctx->dc);
+    DestroyWindow(ctx->window);
+}
+
+unsigned int CDECL wined3d_get_gl_texture(struct wined3d_texture *texture)
+{
+    struct wined3d_device *device = texture->resource.device;
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_texture_gl *gl_texture;
+    GLsync fence;
+
+    TRACE("texture %p.\n", texture);
+
+    if (!(gl_info = wined3d_prepare_vr_gl_context(device)))
+        return 0;
+
+    fence = wined3d_cs_synchronize(device->cs);
+    GL_EXTCALL(glWaitSync(fence, 0, GL_TIMEOUT_IGNORED));
+    GL_EXTCALL(glDeleteSync(fence));
+
+    checkGLcall("synchronize CS");
+
+    gl_texture = wined3d_texture_gl(texture);
+    return gl_texture->texture_rgb.name;
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 519b0292483..7ded39f9db8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3011,6 +3011,14 @@ struct wined3d_stateblock_state
     struct wined3d_light_state light_state;
 };
 
+struct wined3d_vr_gl_context
+{
+    HWND window;
+    HDC dc;
+    HGLRC gl_ctx;
+    const struct wined3d_gl_info *gl_info;
+};
+
 struct wined3d_device
 {
     LONG ref;
@@ -3090,6 +3098,8 @@ struct wined3d_device
     /* Context management */
     struct wined3d_context **contexts;
     UINT context_count;
+
+    struct wined3d_vr_gl_context vr_context;
 };
 
 void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb,
@@ -3809,6 +3819,10 @@ void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_t
 void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
         wined3d_cs_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
 
+GLsync wined3d_cs_synchronize(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
+
+void wined3d_destroy_gl_vr_context(struct wined3d_vr_gl_context *ctx) DECLSPEC_HIDDEN;
+
 static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
         unsigned int start_idx, unsigned int count, const void *constants)
 {
diff --git a/include/wine/wined3d-interop.idl b/include/wine/wined3d-interop.idl
index c5395ccc0ed..b1bda8ada76 100644
--- a/include/wine/wined3d-interop.idl
+++ b/include/wine/wined3d-interop.idl
@@ -28,6 +28,8 @@ import "d3d11.idl";
 interface IWineD3D11Texture2D : ID3D11Texture2D
 {
     void access_gl_texture(gl_texture_callback callback, IUnknown *depth_texture, const void *data, unsigned int data_size);
+
+    unsigned int get_gl_texture();
 }
 
 typedef void (__cdecl *user_cs_callback)(const void *data, unsigned int data_size);
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 4754901265f..9bafa8b0f46 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2758,6 +2758,8 @@ typedef void (__cdecl *wined3d_gl_texture_callback)(unsigned int gl_texture, uns
 void __cdecl wined3d_access_gl_texture(struct wined3d_texture *texture,
         wined3d_gl_texture_callback callback, struct wined3d_texture *depth_texture, const void *data, unsigned int size);
 
+unsigned int __cdecl wined3d_get_gl_texture(struct wined3d_texture *texture);
+
 typedef void (__cdecl *wined3d_cs_callback)(const void *data, unsigned int size);
 
 void __cdecl wined3d_device_run_cs_callback(struct wined3d_device *device,
From 315bed86ed974208c0be4e85a3b52360dbe02761 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Fri, 21 Sep 2018 12:04:07 +0200
Subject: [PATCH] wined3d: Load TEXTURE_RGB location for synchronous texture
 access.

---
 dlls/wined3d/cs.c              | 10 +++++++---
 dlls/wined3d/texture.c         |  2 +-
 dlls/wined3d/wined3d_private.h |  2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 1f1883cafea..85cbc4cdbbc 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -468,6 +468,7 @@ struct wined3d_cs_wait_idle
 struct wined3d_cs_fence
 {
     enum wined3d_cs_op opcode;
+    struct wined3d_texture *texture;
     GLsync *fence;
 };
 
@@ -2618,6 +2619,8 @@ static void wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data)
     context = context_acquire(cs->device, NULL, 0);
     gl_info = wined3d_context_gl(context)->gl_info;
 
+    wined3d_texture_load_location(op->texture, 0, context, WINED3D_LOCATION_TEXTURE_RGB);
+
     fence = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
     wined3d_context_gl(context)->gl_info->gl_ops.gl.p_glFlush();
 
@@ -2628,13 +2631,14 @@ static void wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data)
     context_release(context);
 }
 
-static GLsync wined3d_cs_emit_fence(struct wined3d_cs *cs)
+static GLsync wined3d_cs_emit_fence(struct wined3d_cs *cs, struct wined3d_texture *texture)
 {
     struct wined3d_cs_fence *op;
     GLsync fence;
 
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
     op->opcode = WINED3D_CS_OP_FENCE;
+    op->texture = texture;
     op->fence = &fence;
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
@@ -2643,9 +2647,9 @@ static GLsync wined3d_cs_emit_fence(struct wined3d_cs *cs)
     return fence;
 }
 
-GLsync wined3d_cs_synchronize(struct wined3d_cs *cs)
+GLsync wined3d_cs_synchronize(struct wined3d_cs *cs, struct wined3d_texture *texture)
 {
-    return wined3d_cs_emit_fence(cs);
+    return wined3d_cs_emit_fence(cs, texture);
 }
 
 static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index bb2a557c972..5d64e3895d2 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3989,7 +3989,7 @@ unsigned int CDECL wined3d_get_gl_texture(struct wined3d_texture *texture)
     if (!(gl_info = wined3d_prepare_vr_gl_context(device)))
         return 0;
 
-    fence = wined3d_cs_synchronize(device->cs);
+    fence = wined3d_cs_synchronize(device->cs, texture);
     GL_EXTCALL(glWaitSync(fence, 0, GL_TIMEOUT_IGNORED));
     GL_EXTCALL(glDeleteSync(fence));
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7ded39f9db8..ec1db8e3edc 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3819,7 +3819,7 @@ void wined3d_cs_emit_gl_texture_callback(struct wined3d_cs *cs, struct wined3d_t
 void wined3d_cs_emit_user_callback(struct wined3d_cs *cs,
         wined3d_cs_callback callback, const void *data, unsigned int size) DECLSPEC_HIDDEN;
 
-GLsync wined3d_cs_synchronize(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
+GLsync wined3d_cs_synchronize(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 
 void wined3d_destroy_gl_vr_context(struct wined3d_vr_gl_context *ctx) DECLSPEC_HIDDEN;
 
From dd60e9524d6bf611154c451e50ac7e168caf623f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Fri, 21 Sep 2018 12:17:15 +0200
Subject: [PATCH] d3d11: Pass IWineD3D11Texture2D to access_gl_texture().

---
 dlls/d3d11/texture.c             | 21 +++++++--------------
 include/wine/wined3d-interop.idl |  3 ++-
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index 95328043789..8fc75fd6f92 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -719,27 +719,20 @@ static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(IWineD3D11Texture2D *iface
 }
 
 static void STDMETHODCALLTYPE d3d11_texture2d_access_gl_texture(IWineD3D11Texture2D *iface,
-        gl_texture_callback callback, IUnknown *depth_unk, const void *data, unsigned int size)
+        gl_texture_callback callback, IWineD3D11Texture2D *depth_texture, const void *data, unsigned int size)
 {
     struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface), *depth_tex = NULL;
-    IWineD3D11Texture2D *depth_d3d11 = NULL;
+    struct wined3d_texture *wined3d_depth_texture = NULL;
 
-    TRACE("iface %p, callback %p, data %p, size %u.\n", iface, callback, data, size);
+    TRACE("iface %p, callback %p, depth_texture %p, data %p, size %u.\n",
+            iface, callback, depth_texture, data, size);
 
     wined3d_mutex_lock();
 
-    if (depth_unk)
-    {
-        HRESULT hr;
-        hr = IUnknown_QueryInterface(depth_unk, &IID_IWineD3D11Texture2D, (void**)&depth_d3d11);
-        if(hr == S_OK)
-            depth_tex = impl_from_IWineD3D11Texture2D(depth_d3d11);
-    }
-
-    wined3d_access_gl_texture(texture->wined3d_texture, callback, depth_tex ? depth_tex->wined3d_texture : NULL, data, size);
+    if (depth_texture)
+        wined3d_depth_texture = impl_from_IWineD3D11Texture2D(depth_texture)->wined3d_texture;
 
-    if (depth_d3d11)
-        IWineD3D11Texture2D_Release(depth_d3d11);
+    wined3d_access_gl_texture(texture->wined3d_texture, callback, wined3d_depth_texture, data, size);
 
     wined3d_mutex_unlock();
 }
diff --git a/include/wine/wined3d-interop.idl b/include/wine/wined3d-interop.idl
index b1bda8ada76..f960e2f6d9d 100644
--- a/include/wine/wined3d-interop.idl
+++ b/include/wine/wined3d-interop.idl
@@ -27,7 +27,8 @@ import "d3d11.idl";
 ]
 interface IWineD3D11Texture2D : ID3D11Texture2D
 {
-    void access_gl_texture(gl_texture_callback callback, IUnknown *depth_texture, const void *data, unsigned int data_size);
+    void access_gl_texture(gl_texture_callback callback,
+            IWineD3D11Texture2D *depth_texture, const void *data, unsigned int data_size);
 
     unsigned int get_gl_texture();
 }
From ba0f40e82ab9ed82760aed91476842d844cd55bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <joseph.kucia@gmail.com>
Date: Thu, 11 Oct 2018 11:31:43 +0200
Subject: [PATCH] d3d11: Remove unused 'depth_tex' variable.

---
 dlls/d3d11/texture.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index 8fc75fd6f92..8001d62e2c1 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -721,7 +721,7 @@ static void STDMETHODCALLTYPE d3d11_texture2d_GetDesc(IWineD3D11Texture2D *iface
 static void STDMETHODCALLTYPE d3d11_texture2d_access_gl_texture(IWineD3D11Texture2D *iface,
         gl_texture_callback callback, IWineD3D11Texture2D *depth_texture, const void *data, unsigned int size)
 {
-    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface), *depth_tex = NULL;
+    struct d3d_texture2d *texture = impl_from_IWineD3D11Texture2D(iface);
     struct wined3d_texture *wined3d_depth_texture = NULL;
 
     TRACE("iface %p, callback %p, depth_texture %p, data %p, size %u.\n",
From ed20cf5a06bb63eaae2b1545d2e0d5b4616208dc Mon Sep 17 00:00:00 2001
From: GloriousEggroll <gloriouseggroll@gmail.com>
Date: Sun, 18 Aug 2019 19:05:52 -0600
Subject: [PATCH] wined3d

---
 dlls/wined3d/wined3d.spec | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index bead68fc22..4e5efea8f1 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -326,3 +326,8 @@
 @ cdecl wined3d_vertex_declaration_incref(ptr)
 
 @ cdecl wined3d_extract_shader_input_signature_from_dxbc(ptr ptr long)
+
+@ cdecl wined3d_access_gl_texture(ptr ptr ptr long)
+@ cdecl wined3d_device_run_cs_callback(ptr ptr ptr long)
+@ cdecl wined3d_device_wait_idle(ptr)
+@ cdecl wined3d_get_gl_texture(ptr)
-- 
2.21.0

 
